package com.allwees.bs.core.model.stat;

import com.baomidou.mybatisplus.core.enums.IEnum;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.allwees.bs.core.model.useraction.constant.EActionType;
import com.allwees.bs.core.model.useraction.constant.EPvType;
import lombok.Getter;

import javax.persistence.Transient;

/**
 * 日统计数据类型
 *
 * @author yangylsky
 * @since 2020-04-14
 */
@Getter
public enum EStatType implements IEnum<String> {
	/*========================begin of USER====================*/

    USER_REG("新注册用户数", "统计周期内，注册成功的用户数", EActionType.USER_REG),
    USER_LOGIN("用户登录数", "统计周期内，账号登录成功的用户数，系统自动续登不纳入计算", EStatValueType.AVG, EActionType.USER_LOGIN),
    USER_REG_3RD("第三方注册用户数", "统计周期内，第三方注册成功的用户数", EActionType.USER_REG_3RD),
    USER_LOGIN_3RD("第三方登录用户数", "第三方登录用户数", EActionType.USER_LOGIN_3RD),

    @StatSource
    USER_COUNT("用户数", "用户数", EStatValueType.LAST1),
    @StatSource
    USER_REGULAR("老用户数", "下过订单的用户数", EStatValueType.LAST1),
    USER_LIVENESS("活跃用户数", "有过PV的用户数", EStatValueType.AVG),

	/*========================end of USER====================*/

	/*========================begin of PRODUCT====================*/
    /**
     * 当前有效商品总数
     */
    @StatSource
    P_COUNT("当前有效商品总数", "当前有效商品总数", EStatValueType.LAST1),

    /**
     * 被访问商品数
     */
    P_VIEW_COUNT("被访问商品数", "统计周期内，平台所有被浏览过的商品详情页的商品总数", EStatValueType.AVG, EPvType.P_DETAIL),
	/*========================end of PRODUCT====================*/

	/*========================begin of SITE PV/UV====================*/

	SITE_PV("网站访问量PV", "统计周期内，Page View，整个网站被浏览的次数"),
    SITE_UV("网站访问量UV", "统计周期内，Unique Visitor，整个网站的访问人数", EStatValueType.AVG),

    /**
     * IP访问数
     */
    SITE_IPV("IP访问数", "统计周期内，访问过该网站的IP地址个数，去重，一个IP可能会对应多个UV", EStatValueType.AVG),

    /**
     * 只浏览了一个页面的UV（仅日报表）
     */
    SITE_1UV("只浏览了一个页面的UV", "只浏览了一个页面的UV"),

	/**
	 * 人均访问次数 - 统计周期内，访问过该网站的用户平均浏览的页面数，即PV/UV
	 */
    @Transient
	SITE_USER_AVG_COUNT("人均访问次数", "统计周期内，访问过该网站的用户平均浏览的页面数，即PV/UV", EStatValueType.DOUBLE1),

	/**
	 * 跳失率 - 统计周期内，只浏览了一个页面的UV/网站的总UV
	 */
    @Transient
	SITE_BOUNCE_RATE("跳失率", "统计周期内，只浏览了1个页面的UV/网站总的UV", EStatValueType.PERCENT),

    HOME_PV("Home PV", "Home PV", EPvType.HOME),
    BANNER_PV("Banner PV", "Banner PV", EPvType.BANNER),
    HOME_UV("Home UV", "Home UV", EStatValueType.AVG, EPvType.HOME),
    BANNER_UV("Banner UV", "Banner UV", EStatValueType.AVG, EPvType.BANNER),

	/*========================end of SITE PV/UV====================*/

	/*========================begin of PRODUCT PV/UV====================*/

    P_VIEW_PV("商品详情浏览量PV", "统计周期内，平台所有商品详情页被浏览的次数", EPvType.P_DETAIL),
    P_VIEW_UV("商品详情浏览量UV", "统计周期内，平台所有商品详情页被浏览的人数", EStatValueType.AVG, EPvType.P_DETAIL),

	/**
	 * 被访问商品数占比 - 统计周期内，被访问过详情的商品数/平台已上架的商品数
	 */
    @Transient
	P_VIEW_PV_COUNT_RATE("被访问商品数占比", "统计周期内，被访问过详情的商品数/平台已上架的商品数，会受到平台产品上下架影响", EStatValueType.PERCENT),

    P_LIST_SEARCH_PV("搜索词PV", "", EPvType.P_LIST_SEARCH),
    P_LIST_CATEGORY_PV("分类PV", "分类PV", EPvType.P_LIST_CATEGORY),
    P_LIST_HOT_SELL_TAG_PV("热门标签PV", "热门标签PV", EPvType.P_LIST_HOT_SELL_TAG),
    P_LIST_PROMOTION_TAG_PV("专区PV", "专区PV", EPvType.P_LIST_PROMOTION_TAG),

    P_LIST_SEARCH_UV("搜索词UV", "搜索词UV", EStatValueType.AVG, EPvType.P_LIST_SEARCH),
    P_LIST_CATEGORY_UV("分类UV", "分类UV", EStatValueType.AVG, EPvType.P_LIST_CATEGORY),
    P_LIST_HOT_SELL_TAG_UV("热门标签UV", "热门标签UV", EStatValueType.AVG, EPvType.P_LIST_HOT_SELL_TAG),
    P_LIST_PROMOTION_TAG_UV("专区UV", "专区UV", EStatValueType.AVG, EPvType.P_LIST_PROMOTION_TAG),

	/*========================end of PRODUCT PV/UV====================*/

	/*========================begin of ORDER====================*/
    /**
     * 下单数量
     */
    ORDER_CREATE_COUNT("下单数", "统计周期内，平台所有下单的订单数量", EActionType.ORDER_CREATE),

    /**
     * 下单用户数
     */
    ORDER_USER_COUNT("下单用户数", "统计周期内，平台所有下单人数每日去重的累计，一个人在一天内下单多笔，算1人", EStatValueType.AVG, EActionType.ORDER_CREATE),

    /**
     * 下单新用户数
     */
    ORDER_NEW_USER_COUNT("下单新用户数", "首次下单的用户数", EActionType.ORDER_CREATE),

    /**
     * 下单老用户数
     */
    ORDER_REGULAR_USER_COUNT("下单老用户数", "下过单的老用户再次下单数", EStatValueType.AVG, EActionType.ORDER_CREATE),

    /**
     * 下单总金额
     */
    ORDER_AMT("下单总金额", "统计周期内，平台所有下单的订单总金额，不考虑订单取消的金额", EStatValueType.DOUBLE2, EActionType.ORDER_CREATE),

    /**
     * 下单SKU件数
     */
    ORDER_SKU_COUNT("下单SKU件数", "统计周期内，平台所有下单的订单中商品的件数总和", EActionType.ORDER_CREATE),

    /**
     * 支付订单数
     */
    ORDER_PAY_COUNT("支付订单数", "统计周期内，平台所有支付成功的订单数", EActionType.ORDER_PAY),

    /**
     * 支付总金额
     */
    GMV("GMV", "统计周期内，平台所有支付成功的订单金额总和，不考虑用户退货金额", EStatValueType.DOUBLE2, EActionType.ORDER_PAY),

    /**
     * 支付用户数
     */
    ORDER_PAY_USER_COUNT("支付用户数", "统计周期内，平台所有支付成功的用户数，去重，一个人在一天内下单多笔，算1人", EStatValueType.AVG, EActionType.ORDER_PAY),

    /**
     * 支付件数
     */
    ORDER_PAY_SKU_COUNT("支付件数", "统计周期内，平台所有支付成功的订单中商品的件数总和", EActionType.ORDER_PAY),

	/**
	 * 访客-下单转化率 - 统计周期内，平台所有下单用户数/平台所有商品的访客数，即来访客户转化为下单用户的比例
	 */
    @Transient
    CLIENT_ORDER_CONVERSION_RATE("访客-下单转化率", "统计周期内，平台所有下单用户数/平台所有商品的访客数，即来访客户转化为下单用户的比例", EStatValueType.PERCENT),

	/**
	 * 访客-支付转化率 - 统计周期内，平台所有支付成功的用户数/平台所有商品的访客数
	 */
    @Transient
    CLIENT_PAY_CONVERSION_RATE("访客-支付转化率", "统计周期内，平台所有支付成功的用户数/平台所有商品的访客数", EStatValueType.PERCENT),

	/**
	 * 订单-支付转化率 - 统计周期内，平台所有支付成功的用户数/平台所有下单用户数
	 */
    @Transient
    ORDER_PAY_CONVERSION_RATE("订单-支付转化率", "统计周期内，平台所有支付成功的用户数/平台所有下单用户数", EStatValueType.PERCENT),

	/*========================end of ORDER====================*/

	/*========================begin of REFUND====================*/

    ORDER_REFUND_USER_COUNT("退货人数", "退货人数", EStatValueType.AVG, EActionType.SKU_UNSHIPPED_REFUND, EActionType.SKU_SHIPPED_REFUND),
    ORDER_REFUND_COUNT("退货订单数", "退货订单数", EActionType.SKU_UNSHIPPED_REFUND, EActionType.SKU_SHIPPED_REFUND),
    SKU_REFUND_COUNT("退货SKU数", "退货SKU数", EActionType.SKU_UNSHIPPED_REFUND, EActionType.SKU_SHIPPED_REFUND),
    SKU_ORDER_REFUND_COUNT("订单退货SKU数", "订单退货SKU数（以退货时间统计）", EActionType.SKU_UNSHIPPED_REFUND, EActionType.SKU_SHIPPED_REFUND),
    SKU_UNSHIPPED_REFUND_COUNT("退货[未发货]SKU数", "退货[未发货]SKU数", EActionType.SKU_UNSHIPPED_REFUND),
    SKU_SHIPPED_REFUND_COUNT("退货[已发货]SKU数", "退货[已发货]SKU数", EActionType.SKU_SHIPPED_REFUND),

    /**
     * 退货率
     */
    @Transient
    REFUND_RATE("退货率", "退货SKU数/下单SKU件数", EStatValueType.PERCENT),
	/*========================end of REFUND====================*/

	/*========================begin of CART====================*/

    CART_ADD_SKU_COUNT("加购件数", "加购件数", EActionType.CART_ADD),
    CART_ADD_USER_COUNT("加购用户数", "加购用户数", EStatValueType.AVG, EActionType.CART_ADD),
    @Transient
    CART_REDUCE("减购", "减购", EActionType.CART_REDUCE),

	/*========================end of CART====================*/

	/*========================begin of BS STAT====================*/
    /**
     * 复购率
     */
    @Transient
    REGULAR_USER_BUY_RATE("复购率", "下单老用户数/下单用户数", EStatValueType.PERCENT),

    /**
     * 老用户复购率
     */
    @Transient
    LIVENESS_REGULAR_USER("老用户复购率", "下单老用户数/老用户数", EStatValueType.PERCENT),

    /**
     * 每用户GMV
     */
    @Transient
    GMV_PER_USER("每用户GMV", "GMV/支付用户数", EStatValueType.DOUBLE2),

    /**
     * 客单价
     */
    @Transient
    ATV("客单价", "GMV/订单数", EStatValueType.DOUBLE2)

	/*========================end of BS STAT====================*/
	;

    private String desc;

    private String summary;

    private EStatValueType valueType;

    private EActionType[] actionTypes;

    private EPvType[] pvTypes;

	EStatType(String desc, String summary) {
    	this(desc, summary, EStatValueType.INT);
	}

    EStatType(String desc, String summary, EActionType... actionTypes) {
    	this(desc, summary);
        this.actionTypes = actionTypes;
    }

    EStatType(String desc, String summary, EPvType... pvTypes) {
    	this(desc, summary);
        this.pvTypes = pvTypes;
    }

	EStatType(String desc, String summary, EStatValueType valueType) {
		this.desc = desc;
		this.summary = summary;
		this.valueType = valueType;
	}

    EStatType(String desc, String summary, EStatValueType valueType, EActionType... actionTypes) {
    	this(desc, summary, valueType);
        this.actionTypes = actionTypes;
    }

    EStatType(String desc, String summary, EStatValueType valueType, EPvType... pvTypes) {
    	this(desc, summary, valueType);
        this.pvTypes = pvTypes;
    }

	@SuppressWarnings("rawtypes")
	public String getTypes() {
		Enum[] enums = ArrayUtils.isEmpty(actionTypes) ? pvTypes : actionTypes;
		if(ArrayUtils.isEmpty(enums)) {
			return null;
		}

		StringBuilder str = new StringBuilder();
		for(int i = 0; i < enums.length; i++) {
			if(i != 0) {
				str.append(",");
			}
			str.append("'").append(enums[i].name()).append("'");
		}
		return str.toString();
	}

	@Override
	public String getValue() {
		return name();
	}
}
